#include "app_all_airbag.h"

#include "common_debug.h"
#include "inf_pump.h"

static void     app_all_airbag_apply_mode(airbag_system_t *system, uint32_t mode);
static result_e app_all_airbag_validate_mode(uint32_t mode);

static airbag_system_t all_airbag_system;
static airbag_t        all_airbag_airbags[ALL_AIRBAG_IDX_MAX];
static cps121_idx_e    all_airbag_sensor_mapping[ALL_AIRBAG_IDX_MAX];

/* 阀门通道配置 */
static airbag_valve_config_t all_airbag_valve_configs[ALL_AIRBAG_IDX_MAX] = {
    [ALL_AIRBAG_IDX_YT1] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH10, // YT1
        .deflate_valve_ch = SOLENOID_VALVE_CH11, // YT1R
        .pressure_sensor_idx = CPS121_IDX_0,
    },
    [ALL_AIRBAG_IDX_YT2] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH12, // YT2
        .deflate_valve_ch = SOLENOID_VALVE_CH13, // YT2R
        .pressure_sensor_idx = CPS121_IDX_1,
    },
    [ALL_AIRBAG_IDX_YT3] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH14, // YT3
        .deflate_valve_ch = SOLENOID_VALVE_CH15, // YT3R
        .pressure_sensor_idx = CPS121_IDX_2,
    },
    [ALL_AIRBAG_IDX_YT4] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH16, // YT4
        .deflate_valve_ch = SOLENOID_VALVE_CH17, // YT4R
        .pressure_sensor_idx = CPS121_IDX_3,
    },
    [ALL_AIRBAG_IDX_YT5] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH18, // YT5
        .deflate_valve_ch = SOLENOID_VALVE_CH19, // YT5R
        .pressure_sensor_idx = CPS121_IDX_4,
    },
    [ALL_AIRBAG_IDX_YT6] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH20, // YT6
        .deflate_valve_ch = SOLENOID_VALVE_CH21, // YT6R
        .pressure_sensor_idx = CPS121_IDX_5,
    },
    [ALL_AIRBAG_IDX_YT7] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH22, // YT7
        .deflate_valve_ch = SOLENOID_VALVE_CH23, // YT7R
        .pressure_sensor_idx = CPS121_IDX_6,
    },
    [ALL_AIRBAG_IDX_YT8] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH24, // YT8
        .deflate_valve_ch = SOLENOID_VALVE_CH25, // YT8R
        .pressure_sensor_idx = CPS121_IDX_7,
    },
    [ALL_AIRBAG_IDX_YT9] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH26, // YT9
        .deflate_valve_ch = SOLENOID_VALVE_CH27, // YT9R
        .pressure_sensor_idx = CPS121_IDX_8,
    },
    [ALL_AIRBAG_IDX_YT10] = {
        .inflate_valve_ch = SOLENOID_VALVE_CH28, // YT10
        .deflate_valve_ch = SOLENOID_VALVE_CH29, // YT10R
        .pressure_sensor_idx = CPS121_IDX_9,
    },
};

/* 侧翼系统配置 */
static const airbag_system_config_t all_airbag_config = {
    .max_inflate_time_ms    = 60 * 1000,
    .dispatching_cycle_ms   = 50,
    .airbag_count           = ALL_AIRBAG_IDX_MAX,
    .valve_configs          = all_airbag_valve_configs,
    .air_pressure_threshold = 165, /* 气压保护阈值 165 KPa */
};

/* 回调函数集合 */
static const airbag_system_callbacks_t all_airbag_callbacks = {
    .apply_mode    = app_all_airbag_apply_mode,
    .validate_mode = app_all_airbag_validate_mode,
};

/**
 * @brief 初始化全系统
 *
 * @return result_e 初始化结果, 初始化成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e app_all_airbag_init(void)
{
    all_airbag_system.airbags        = all_airbag_airbags;
    all_airbag_system.sensor_mapping = all_airbag_sensor_mapping;
    return app_airbag_system_init(&all_airbag_system, &all_airbag_config, AIRBAG_SYSTEM_TYPE_ALL,
                                  &all_airbag_callbacks);
}

/**
 * @brief 设置全系统运行模式
 *
 * @param   mode        运行模式
 * @return  result_e    设置结果, 设置成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e app_all_airbag_set_mode(all_airbag_mode_e mode)
{
    return app_airbag_system_set_mode(&all_airbag_system, (uint32_t)mode);
}

/**
 * @brief 停止全系统运行
 *
 * @return result_e 停止结果, 停止成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e app_all_airbag_stop(void) { return app_airbag_system_stop(&all_airbag_system); }

/**
 * @brief 处理全系统运行状态, 在调度器中循环调度
 *
 */
void app_all_airbag_handle(void) { app_airbag_system_handle(&all_airbag_system); }

/**
 * @brief 获取当前全系统运行模式
 *
 * @return all_airbag_mode_e 当前运行模式
 */
all_airbag_mode_e app_all_airbag_get_mode(void)
{
    return (all_airbag_mode_e)app_airbag_system_get_mode(&all_airbag_system);
}

/**
 * @brief 获取指定全系统气袋(支撑)状态
 *
 * @param   airbag_idx      气袋索引
 * @return  airbag_state_e  气袋支撑状态
 */
airbag_state_e app_all_airbag_get_airbag_state(all_airbag_idx_e airbag_idx)
{
    return app_airbag_system_get_airbag_state(&all_airbag_system, (uint32_t)airbag_idx);
}

/**
 * @brief 获取指定全系统气袋压力值
 *
 * @param airbag_idx    气袋索引
 * @return uint32_t     气袋压力值, 单位为KPa, 0表示未获取到
 */
uint32_t app_all_airbag_get_air_pressure(all_airbag_idx_e airbag_idx)
{
    return app_airbag_system_get_air_pressure(&all_airbag_system, (uint32_t)airbag_idx);
}

/**
 * @brief 应用侧翼系统运行模式
 *
 * @param system    侧翼系统指针
 * @param mode      运行模式
 */
static void app_all_airbag_apply_mode(airbag_system_t *system, uint32_t mode)
{
    all_airbag_mode_e all_mode = (all_airbag_mode_e)mode;

    switch (all_mode) {
    case ALL_MODE_INSIDE: // inside 充气
        inf_pump_air_inflation();
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT1, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT2, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT3, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT4, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT5, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT6, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT7, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT8, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT9, AIRBAG_STATE_INFLATE);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT10, AIRBAG_STATE_INFLATE);
        break;
    case ALL_MODE_OUTSIDE: // outside 抽气
        inf_pump_air_exhaust();
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT1, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT2, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT3, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT4, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT5, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT6, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT7, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT8, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT9, AIRBAG_STATE_EXHAUST);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT10, AIRBAG_STATE_EXHAUST);
        break;
    case ALL_MODE_KEEP: // keep 同保压
        inf_pump_air_stop();
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT1, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT2, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT3, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT4, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT5, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT6, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT7, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT8, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT9, AIRBAG_STATE_KEEP);
        app_airbag_system_ctrl_airbag(system, ALL_AIRBAG_IDX_YT10, AIRBAG_STATE_KEEP);
        break;
    }
}

/**
 * @brief 验证全系统运行模式
 *
 * @param   mode         运行模式
 * @return  result_e     验证结果, 验证成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
static result_e app_all_airbag_validate_mode(uint32_t mode)
{
    all_airbag_mode_e all_mode = (all_airbag_mode_e)mode;
    if (all_mode < ALL_MODE_INSIDE || all_mode >= ALL_MODE_MAX) {
        return RESULT_STATUS_INVALID_PARAM;
    }

    return RESULT_STATUS_OK;
}
